#include <iostream>
#include <functional>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <list>
#include <map>
using namespace std;

struct Node {
	int t;
	float val;
	Node(int a, float b) :t(a), val(b) {}
};

struct Edge {
	int n1, n2;
	float w;
};

int main()
{
	string type; cin >> type; //cout << type << endl;
	bool DUN = 0, GN = 0; // 有向无向、带不带权
	if (type == "DG")  DUN = 1, GN = 0;
	if (type == "DN")  DUN = 1, GN = 1;
	if (type == "UDG") DUN = 0, GN = 0;
	if (type == "UDN") DUN = 0, GN = 1;
	int n; cin >> n; vector<string> nodes(n);
	map<string, int> ntoi; // node to index
	for (int i = 0; i < n; i++) {
		cin >> nodes[i]; 
		ntoi[nodes[i]] = i;
	}
	string flag; cin >> flag;
	vector<list<Node>> graph(n);
	int k; cin >> k; //cout << k << endl;
	vector<Edge> path(k); // 带权的话 给权值留个位置
	for (int i = 0; i < k; i++) cin >> path[i].n1 >> path[i].n2;
	if (GN) for (int i = 0; i < k; i++)  cin >> path[i].w;
	int u; cin >> u;
	float ans; cin >> ans;

	vector<int> ufs(n, -1);
	function<int(int)> parent = [&](int cur) {
		if (ufs[cur] < 0) return cur;
		return ufs[cur] = parent(ufs[cur]);
	};
	sort(path.begin(), path.end(), [](auto& l, auto& r) {return l.w < r.w; });
	for (auto& edge : path) {
		int p1 = parent(edge.n1);
		int p2 = parent(edge.n2);
		if (p1 == p2) continue;
		ufs[p1] += ufs[p2];
		ufs[p2] = p1;
		ans += edge.w;
	}

	cout << ans;
	return 0;
}